﻿/* 
* Copyright (c) 2009, SCUT 06级计科2班软件工程第6小组
* All rights reserved. 
*
* 作    者：张家秀
* 完成日期：2009年7月*日 
*  
* 摘    要：用户
*
* 备    注：
*
*/
using System;
using System.Web.SessionState;
using System.Web;

namespace SE6
{
/*用户管理：
 * 公开档案，可供任何人检索、下载、以及查看详情
 * 
 * 
 * 
 */
    public enum Role
    {
	//用户登陆系统必须具备的角色
		BaseUser = 1, // 基本用户角色
	//用户的基本功能
		UploadArchives = BaseUser*2, //2，档案上传角色
		DownloadArchives = UploadArchives * 2,   //4，档案下载角色
		UpdateArchives = DownloadArchives * 2,    //8，档案更新角色
		DeleteArchives = UpdateArchives * 2,      //16，档案删除角色
		LeaveMessage = DeleteArchives * 2,	//32，留言角色
	//管理员功能，
		Admin = LeaveMessage * 2,//管理员角色开始，用于判断，不是真正的用户角色,User.IsAdministrator依赖于此
		LeaveWordManager = LeaveMessage * 2,	//64，【留言管理】角色，删除/设精/置顶帖子
		ArchiveManager = LeaveWordManager*2,  //128,【档案管理】角色，删除/更新/下载/审核档案
		UserManager = ArchiveManager*2,     //256,【用户管理】角色，删除/封禁用户（管理角色的用户除外），用户授权功能除外
		SystemManager = UserManager*2,//512,【系统管理】角色,配置系统功能/配置系统服务
	//超级管理员
		God = SystemManager * 2,        //1024,【超级管理员】角色，任何功能，包括授权其他用户以角色
		UserRoleAssign=God,//【用户授权】角色，与【超级管理员】角色等同
    };
    public class User
    {
        public const Int32 NON_EXISTS_ID = 0;

		//用户是否处于激活状】即是否拥有【基本用户】角色
		public Boolean IsUserActive()	
		{	
			return IsOwnerRole(Role.BaseUser);	
		}
		public void ChangeActiveStatus()
		{
			if (IsUserActive())
				RemoveRole(Role.BaseUser);
			else
				AddRole(Role.BaseUser);
		}
		#region 用户基本功能权限检测

		//【删除档案】,判断该用户能否删除档案ar
		//返回true条件为：档案属主且拥有【档案删除】角色， 或拥有【超级管理员】角色， 或者拥有【档案管理】角色
		public Boolean CanDelete(Archive ar)
		{
			return ar.OwnerID == _id && IsOwnerRole(Role.DeleteArchives) || IsArchiveManager();
		}
		//【更新档案】,判断该用户能否更新档案ar的信息
		//返回true条件为：档案属主且拥有【档案更新】角色， 或拥有【超级管理员】角色， 或者拥有【档案管理】角色
		public Boolean CanUpdate(Archive ar)
		{
			return ar.OwnerID == _id && IsOwnerRole(Role.UpdateArchives) || IsArchiveManager();
		}

		//【更新档案】,判断该用户能否下载secLevel级别的档案
		//返回true条件为：档案属主且拥有【档案下载】角色且积分足够， 或拥有【超级管理员】角色
		public Boolean CanDownload(Archive ar)
		{
			return ar.OwnerID == _id
							&& IsOwnerRole(Role.DownloadArchives) 
							&& _point >= ar.Point
							|| IsSuperMan();
		}
		//【上传档案】,判断该用户能否上传secLevel级别的档案
		//返回true条件为：拥有【超级管理员】角色或 积分足够且（拥有【档案上传】角色，或者拥有【档案管理】角色)
		public Boolean CanUploadArchive()
		{
			return IsOwnerRole(Role.UploadArchives);
		}
		//【留言】
		public Boolean CanLeaveWord()
		{
			return IsOwnerRole(Role.LeaveMessage);
		}
		public Boolean IsUploadPointEnough(ArchiveSecurityLevel secLevel)
		{
			return _point >= SystemMan.GetUploadPoint(secLevel);
		}
// 		public Boolean CanUpload(ArchiveSecurityLevel secLevel)
// 		{
// 			return IsOwnerRole(Role.UploadArchives) && _point >= SystemMan.GetUploadPoint(secLevel);
// 		}
		#endregion

		#region 管理员功能权限检测函数
		//是否管理员用户
		public Boolean IsAdministrator()
		{
			return _roles >= Role.Admin;
		}
		//是否拥有【用户管理】角色
		public Boolean IsUserManager()		
		{		
			return IsOwnerRole(Role.UserManager);
		}
		//是否用户【用户角色授予】
		public Boolean IsRoleAssign()		
		{
			return IsOwnerRole(Role.UserRoleAssign);
		}
		//是否拥有【档案管理】角色
		public Boolean IsArchiveManager()		
		{	
			return IsOwnerRole(Role.ArchiveManager);	
		}
		//是否拥有【系统管理】角色
		public Boolean IsSystemManager() 
		{
			return IsOwnerRole(Role.SystemManager);
		}
		//是否拥有【留言管理】角色
		public Boolean IsLeaveWordManager() 
		{ 
			return IsOwnerRole(Role.LeaveWordManager); 
		}
		//是否拥有【超级管理员】角色
		public Boolean IsSuperMan()
		{
			//!!!默认第一个用户为超级管理员
			return (_roles & Role.God) != 0 || _id==1;
		}
		#endregion

		//判断用户是否拥有role角色，返回true条件为：拥有超级管理员角色或拥有role角色
		private Boolean IsOwnerRole(Role role)
		{
			return IsSuperMan() || (_roles & role) != 0;
		}
		private void RemoveRole(Role role)
		{
			_roles &= ~role;
		}
		private void AddRole(Role role)
		{
			_roles |= role;
		}
		//针对数据库查询
		public User(
			Int32 id, String name, String email, Byte[] firstHashedPassword,
			Byte[] hashedPassword, Byte[] encryptedDESKey,
			String question, Byte[] hashedAnswer, Byte[] answerEncryptedDESKey,
			Int32 point, Role roles, String registerTime, String lastLoginTime, Int32 loginTimes
			)
		{
			_id = id;
			_name = name;
			_email = email;
			_hashedPassword = hashedPassword;
			_firstHashedPassword = firstHashedPassword;
			_encryptedDESKey = encryptedDESKey;
			_desKey = null;//
			_password = null;//
			_question = question;
			_hashedAnswer = hashedAnswer;
			_answerEncryptedDESKey = answerEncryptedDESKey;
			_point = point;
			_roles = roles;
			_registerTime = registerTime;
			_lastLoginTime = lastLoginTime;
			_loginTimes = loginTimes;
			//todo
		}
        //针对用户注册
        public User(String name, String password, String email, String question, String answer)
        {
            _id = 0;
            _name = name;
            _password = password;
            _email = email;
            _hashedPassword = Utility.Hash.Md5(password);
			_firstHashedPassword = _hashedPassword;
			_desKey = DESCoder.GetRandKey();//生成随机密钥
            _encryptedDESKey = DESCoder.Encrypt(DESCoder.ExtractKey(password),_desKey);
            _question = question;
            _hashedAnswer = Utility.Hash.Md5(answer);
			_answerEncryptedDESKey = DESCoder.Encrypt(DESCoder.ExtractKey(answer), _desKey);
            _point = 1000;
            _roles = Role.BaseUser|Role.LeaveMessage
				|Role.UploadArchives|Role.DownloadArchives|Role.UpdateArchives|Role.DeleteArchives;
            _registerTime = System.DateTime.Now.ToString();
			_lastLoginTime = "2009-1-1";
        }
		//加密
		public Byte[] Encrypt(Byte[] content)
		{
			return DESCoder.Encrypt(_desKey, content);
		}
		//解密
		public Byte[] Decrypt(Byte[] content)
		{
			return DESCoder.Decrypt(_desKey, content);
		}
		//显示该用户的详细资料，使用XHTML标签格式化各字段
		public String Render()
		{
			return "";
		}
		//用户登录成功后调用此函数
		//1
		public void Login(String password)
		{
			//更新用户实时数据
			++_loginTimes;
			_lastLoginTime = DateTime.Now.ToString();
			_password = password;
			_desKey = DESCoder.Decrypt(DESCoder.ExtractKey(password), _encryptedDESKey);
		}
		//0:可以登录，1密码正确但用户帐户已被冻结，-1密码错误
		public Int32 LoginResult(String password)
		{
			Byte[] hashedP = Utility.Hash.Md5(password);
			if (!Utility.Util.IsByteArrayEqual(hashedP, _hashedPassword))
				return -1;
			return IsUserActive() ? 0 : 1;
		}
		//下载档案ar扣积分
		public void DownloadArchive(Archive ar)
		{
			_point -= ar.Point;
		}
		//重置密码
		public Boolean ResetPassword(String password,String answer)
		{
			Byte[] hashedAnswer=Utility.Hash.Md5(answer);
			//判断密保回答是否正确
			if (!Utility.Util.IsByteArrayEqual(hashedAnswer,_hashedAnswer))
				return false;
		//开始重置用户密码,更新相关信息
			//a.重置为新密码
			_password=password;
            _hashedPassword = Utility.Hash.Md5(password);
			//b.用回答解密出 原档案密钥
			_desKey= DESCoder.Decrypt(DESCoder.ExtractKey(answer),_answerEncryptedDESKey); 
			//c.用新密码重新加密之
			_encryptedDESKey=DESCoder.Encrypt(DESCoder.ExtractKey(password), _desKey);
			return true;
		}
		//修改用户资料
		public void Update(String email,Int32 point)
		{
			_email = email;
			_point = point;
		}
		//用户详细信息
		public String Render(User logUsr)
		{
			Boolean canUpdate=(logUsr!=null) && (logUsr.ID==_id|| logUsr.IsUserManager());
			Boolean isSuperMan = (logUsr != null) && logUsr.IsSuperMan();
			return
				"<table class='profile'> " +
					"<tr><td class='w'>用户名：</td><td class='author'>"+_name+GetDeleteURL()+
						"</td></tr>"+
					"<tr><td>电子邮箱：</td><td>" +GUI.SmartText(canUpdate,"email",_email)+"</td></tr>"+
					"<tr><td>现有积分：</td><td>"+GUI.SmartText(isSuperMan,"point",_point)+"</td></tr>" +
					"<tr><td>注册时间：</td><td class='time'>" +_registerTime + "</td></tr>" +
					"<tr><td>最后登陆时间：</td><td class='time'>" + _lastLoginTime + "</td></tr>" +
					"<tr><td>登陆次数：</td><td class='time'>" + _loginTimes + "</td></tr>" +
					(isSuperMan && _id != logUsr.ID ?
						("<tr><td>用户功能：</td><td>"+
							"<div>"+
								GUI.SmartCheckBox(IsOwnerRole(Role.BaseUser),"bu","登录")+
								GUI.SmartCheckBox(IsOwnerRole(Role.UploadArchives), "ua", "上传档案") +
								GUI.SmartCheckBox(IsOwnerRole(Role.DownloadArchives), "da", "下载档案") +
								GUI.SmartCheckBox(IsOwnerRole(Role.UpdateArchives), "up", "更新档案") +
								GUI.SmartCheckBox(IsOwnerRole(Role.DeleteArchives), "dela", "删除档案") +
								GUI.SmartCheckBox(IsOwnerRole(Role.LeaveMessage), "lw", "留言") +
							"</div>"+
							"<div>"+
								GUI.SmartCheckBox(IsOwnerRole(Role.LeaveWordManager), "lwm", "留言管理") +
								GUI.SmartCheckBox(IsOwnerRole(Role.ArchiveManager), "am", "档案管理") +
								GUI.SmartCheckBox(IsOwnerRole(Role.SystemManager), "sysm", "系统管理") +
								GUI.SmartCheckBox(IsOwnerRole(Role.UserManager), "um", "用户管理") +
							"</div>"+
							"<div>"+
								GUI.SmartCheckBox(IsSuperMan(), "god", "超级管理员")+
							"</div></td>"
							):""
						)+
				"</table>" + GUI.SmartSubmit(canUpdate,_id);
		}

		//用户管理时显示
		public String SimpleRender(Boolean isOdd,Int32 curPage)
		{
			String css = isOdd ? "class='odd'" : "";
			return 
				"<tr " + css + ">" +
					"<td class='id'>"+_id+"</td>"+
					"<td class='name'>" + GetNameURL() + "</td>" +
					"<td class='time'>" + _lastLoginTime + "</td>" +
					"<td>"+GetDeleteURL()+BaseChangeURL()+"</td>"+
				"</tr>";
		}
		public void UpdateRole(Role role)
		{
			_roles = role;
		}
		//以XHTML标签格式化Topic的标题栏
		public static String RenderHeader()
		{
			return
					"<tr class='odd'>" +
						"<td>ID</td>" +
						"<td>用户名</td>" +
						"<td>最后登陆时间</td>" +
						"<td>操作</td>" +
					"</tr>";
		}
        public Int32 ID
        {
            get { return _id; }
            set { _id = value; }
        }
        public String Name
        {
            get { return _name; }
            // 			set { _name = value; }
        }
        public String Email
        {
            get { return _email; }
            // 			set { _name = value; }
        }
        //哈希后的用户密码（原始密码哈希值）
        public Byte[] FirstHashedPassword
        {
            get { return _firstHashedPassword; }
            //			set { _hashedPassword = value; }
        }
        //哈希后的用户密码
        public Byte[] HashedPassword
        {
            get { return _hashedPassword; }
            //			set { _hashedPassword = value; }
        }
        //哈希后的用户原始密码（注册时的密码哈希值）
        public Byte[] EncryptedDESKey
        {
            get { return _encryptedDESKey; }
            //			set { _encryptedDESKey = value; }
        }
        //密码包含问题
        public String Question
        {
            get { return _question; }
            set { _question = value; }
        }
        //哈希后的密码保护问题答案
        public Byte[] HashedAnswer
        {
            get { return _hashedAnswer; }
            //set { _hashedAnswer = value; }
        }
        //回答加密的  档案加密密钥
        public Byte[] AnswerEncryptedDESKey
        {
            get { return _answerEncryptedDESKey; }
            //			set { _encryptedDESKey = value; }
        }
        public Int32 Point
        {
            get { return _point; }
            //set { _point = value; }
        }
        public Role Roles
        {
            get { return _roles; }
            //set { _roles = value; }
        }
        public String RegisterTime
        {
            get { return _registerTime; }
            //set { _registerTime = value; }
        }
        public String LastLoginTime
        {
            get { return _lastLoginTime; }
            //set { _lastLoginTime = value; }
        }
        public Int32 LoginTimes
        {
            get { return _loginTimes; }
            //set { _loginTimes = value; }
        }
		//删除当前用户
		private String GetDeleteURL()
		{
			SE6.User logUsr = SessionMan.GetLoginUser();
			return (logUsr!=null&&logUsr.ID != _id) ? ("<a class='button' href='par.aspx?t=3&id=" + _id +
				"'>永久删除(请三思)</a>"):"";
		}
		//禁止或允许用户登陆
		private String BaseChangeURL()
		{
			return "<a class='button' href='par.aspx?t=4&id=" + _id + "'>"+
				(IsUserActive()?"<span class='red'>禁止登陆</span>":"允许登陆")+"</a>";
		}
		//详细信息URL
		private String GetNameURL()
		{
			return "<a href='DetailProfile.aspx?id="+_id+"'>"+_name+"</a>";
		}

        private Int32 _id;//用户ID		
        private String _name;//用户名	
        private String _password;//用户输入的密码，临时保存在服务器		
		private Byte[] _desKey;//DES密钥，临时保存在服务器		
        private String _email;//电子信箱	

        private Byte[] _firstHashedPassword; //哈希后的用户原始密码（注册时的密码哈希值）
        private Byte[] _hashedPassword;//哈希后的用户密码		
        private Byte[] _encryptedDESKey; //使用当前用户密码加密后的 档案加密密钥

        private String _question;          //密码保护问题
        private Byte[] _hashedAnswer; //哈希后的密码保护问题答案
        private Byte[] _answerEncryptedDESKey;//回答加密的  档案加密密钥

        private Int32 _point;         //用户积分
        private Role _roles;           //角色集
        private String _registerTime;     //注册时间
        private String _lastLoginTime;       //上次登录时间
        private Int32 _loginTimes;    //登录次数
    }
}
